package com.exe.rege.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.exe.rege.common.CustomException;
import com.exe.rege.dto.SetmealDto;
import com.exe.rege.entity.CategoryEntity;
import com.exe.rege.entity.SetmealDishEntity;
import com.exe.rege.entity.SetmealEntity;
import com.exe.rege.mapper.SetmealMapper;
import com.exe.rege.service.CategoryService;
import com.exe.rege.service.SetmealDishService;
import com.exe.rege.service.SetmealService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, SetmealEntity> implements SetmealService {
    @Autowired
    private SetmealService setmealService;

    @Autowired
    private SetmealDishService setmealDishService;

    @Autowired
    private CategoryService categoryService;

    /**
     * 新增套餐，同时需要保存套餐和菜品的关联关系
     * @param setmealDto
     * @return
     */
    @Override
    @Transactional
    public void saveWithDish(SetmealDto setmealDto) {
        //保存套餐基本信息，执行insert操作
        this.save(setmealDto);

        //获取套餐和菜品关系
        List<SetmealDishEntity> setmealDishes = setmealDto.getSetmealDishes();

        //要先存进setmeal表里后，才会生成setmealId,故需要将dto获取的遍历set进
        List<SetmealDishEntity> setmealDishEntityList = setmealDishes.stream().map(it -> {
            it.setSetmealId(setmealDto.getId());
            return it;
        }).collect(Collectors.toList());

        //批量保存套餐和菜品之间的关联关系，对setmeal_dish表执行insert操作
        setmealDishService.saveBatch(setmealDishEntityList);
    }

    @Override
    public Page<SetmealDto> getPage(int page, int pageSize, String name) {
        //构造分页构造器对象
        Page<SetmealEntity> pageInfo = new Page<>(page, pageSize);
        //缺少套餐分类，还要加对象
        Page<SetmealDto> pageDto = new Page<>();

        //条件构造器，先查套餐基础信息
        LambdaQueryWrapper<SetmealEntity> queryWrapper = new LambdaQueryWrapper<>();
        //添加过滤条件
        queryWrapper.like(name != null, SetmealEntity::getName, name);
        //排序
        queryWrapper.orderByDesc(SetmealEntity::getUpdateTime);
        //执行分页查询
        setmealService.page(pageInfo, queryWrapper);

        //套餐基础信息查好后，将查得的所有信息拷贝进dto
        BeanUtils.copyProperties(pageInfo, pageDto, "records");

        //把records 取出来处理，set进records
        List<SetmealEntity> records = pageInfo.getRecords();

        //将records里的分类id查出分类名，set进dto
        List<SetmealDto> recordsList = records.stream().map(it -> {
            //新建dto对象
            SetmealDto setmealDto = new SetmealDto();
            //将records拷贝进新的dto对象，之后直接将分类name set进dto里
            BeanUtils.copyProperties(it, setmealDto);

            //获取类型id
            Long categoryId = it.getCategoryId();

            //通过id查分类名
            CategoryEntity categoryEntity = categoryService.getById(categoryId);

            //获取分类名
            //判断实体类不为空
            if (categoryEntity != null) {
                String categoryName = categoryEntity.getName();
                setmealDto.setCategoryName(categoryName);
            }

            return setmealDto;
        }).collect(Collectors.toList());

        pageDto.setRecords(recordsList);

        return pageDto;
    }

    /**
     * 删除套餐，套餐停用的时候才能删除，同时删除与菜品关联的数据
     * @param ids
     * @return
     */
    @Override
    @Transactional
    public void removeWithStatus(List<Long> ids) {
        //检查要删除的套餐是否还是启用，启用的话不能直接删除
        //sql逻辑：在传来的id中查找status为1的，抛出异常：
        //select count(*) from setmeal where id in (1,2,3) and status = 1
        LambdaQueryWrapper<SetmealEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SetmealEntity::getId, ids);
        queryWrapper.eq(SetmealEntity::getStatus, 1);
        int count = setmealService.count(queryWrapper);
        if (count > 0){
            throw new CustomException("该套餐启用中，不能直接删除");
        }

        //批量删除套餐数据,对setmeal表操作
        setmealService.removeByIds(ids);

        //这里是setmeal_id，要在这些id里删除对应数据
        //sql逻辑：delete from setmeal_dish where setmeal_id in (ids)
        LambdaQueryWrapper<SetmealDishEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(SetmealDishEntity::getSetmealId, ids);
        //删除套餐和菜品的关联数据，对setmeal_dish表操作
        setmealDishService.remove(lambdaQueryWrapper);
    }

    /**
     * 通过id获取 套餐基础信息 和套餐与菜品的
     * @param id
     * @return
     */
    @Override
    @Transactional
    public SetmealDto getByIdWithDish(Long id) {
        //从setmeal表里获取套餐基础信息
        SetmealEntity setmealEntity = setmealService.getById(id);
        //将基础信息拷贝进dto里
        SetmealDto setmealDto = new SetmealDto();
        BeanUtils.copyProperties(setmealEntity, setmealDto);

        //从setmeal_dish表里获取套餐和菜品的关联数据
        LambdaQueryWrapper<SetmealDishEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SetmealDishEntity::getSetmealId, id);

        List<SetmealDishEntity> list = setmealDishService.list(queryWrapper);

        setmealDto.setSetmealDishes(list);
        return setmealDto;
    }

    @Override
    public void updateWithDish(SetmealDto setmealDto) {
        //先修改套餐基础信息
        this.updateById(setmealDto);

        //按setmeal_id 找到相关联的菜品信息进行修改
        //修改setmeal_dish表，把相应的删了重新写入，因为不知道修改了多少
        //先清理该表
        LambdaQueryWrapper<SetmealDishEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SetmealDishEntity::getSetmealId, setmealDto.getId());
        setmealDishService.remove(queryWrapper);

        //save seatmeal_dish的套餐菜品信息，但这块传过来是没有seatmeal_id的，要从外面拿
        //先获取id
        Long id = setmealDto.getId();
        //获取关联菜品信息
        List<SetmealDishEntity> setmealDishes = setmealDto.getSetmealDishes();
        //将id都放进去
        List<SetmealDishEntity> setmealDishEntities = setmealDishes.stream().map(it -> {
            it.setSetmealId(id);
            return it;
        }).collect(Collectors.toList());

        setmealDishService.saveBatch(setmealDishEntities);
    }

    @Override
    public void changeStatus(Integer status, String ids) {
        //将传过来的多个id组成的字符串分开
        String[] split = ids.split(",");
        //转换成Long数组
        List<Long> idList = Arrays.stream(split)
                .map(it -> Long.parseLong(it.trim()))
                .collect(Collectors.toList());

        //给每一个id new一个套餐对象，遍历set进去
        List<SetmealEntity> setmealEntities = idList.stream().map(it -> {
            SetmealEntity setmealEntity = new SetmealEntity();
            setmealEntity.setId(it);
            setmealEntity.setStatus(status);
            return setmealEntity;
        }).collect(Collectors.toList());

        //批量修改表
        setmealService.updateBatchById(setmealEntities);
    }
}
